home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 126-150 / scopedisk146 / liner / source / search.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  11KB  |  327 lines

  1. /*                                 Search.c                                */
  2. /*The routines in this module handle the search/replace functions of 'Liner*/
  3.  
  4. #include "Globals.h"
  5. #include "SearchWdws.h"
  6.  
  7. #define MAYBE 2
  8. #define NONONO 3
  9.  
  10. struct SearchParameters
  11. {
  12.    char Search[80],Replace[80];
  13.    BYTE rep,cse,partial;
  14. };
  15.  
  16. struct SearchParameters parameters =
  17. {
  18.    "","",FALSE,FALSE,TRUE
  19. };
  20.  
  21. struct Window *SearchWdw,*ReplAllWdw;
  22.  
  23. GetSRParameters()  /*Opens a window to get the parameters for Search/Replace*/
  24. {
  25.    int status;
  26.          
  27.    NewSearchWindow.Screen=(struct Screen *)Screen;
  28.    SearchWdw=(struct Window *)OpenWindow(&NewSearchWindow);
  29.    if(SearchWdw==NULL)
  30.    {
  31.       Leave(0,"Can't open the search/replace window!");
  32.       return(FALSE);
  33.    }
  34.    PrintIText(SearchWdw->RPort,&IntuiTextList1,0,0);
  35.    ActivateGadget(&SearchFor,SearchWdw,NULL);
  36.          /*Activate the Search for... text gadget*/
  37.    
  38.    while((status=MonitorButtons())==NONONO); /*Let user enter info*/
  39.    
  40.    if(status) /*OK, Cancel, or Wait*/
  41.    {
  42.       parameters.rep = !((SrchRplc.Flags & SELECTED)==FALSE);
  43.       parameters.partial = ((PartialWord.Flags & SELECTED)==FALSE);
  44.       parameters.cse = !((CaseSensitive.Flags & SELECTED)==FALSE);
  45.       strcpy(parameters.Search,SearchForSInfo.Buffer);
  46.       strcpy(parameters.Replace,ReplaceWithSInfo.Buffer);
  47.       if(status==MAYBE)
  48.          status=FALSE;
  49.    }
  50.    else
  51.    {     /*Another gadget was toggled*/
  52.       strcpy(SearchForSInfo.Buffer,parameters.Search);
  53.       strcpy(ReplaceWithSInfo.Buffer,parameters.Replace);
  54.       SrchRplc.Flags = (parameters.rep)
  55.             ? GADGHIMAGE+GADGIMAGE+SELECTED : GADGHIMAGE+GADGIMAGE;
  56.       PartialWord.Flags = (parameters.partial)
  57.             ? GADGHIMAGE+GADGIMAGE : GADGHIMAGE+GADGIMAGE+SELECTED;
  58.       CaseSensitive.Flags = (parameters.cse) ? GADGHIMAGE+GADGIMAGE+SELECTED
  59.             : GADGHIMAGE+GADGIMAGE;
  60.    }
  61.       
  62.    CloseWindow(SearchWdw);
  63.    return(status);
  64. }
  65.  
  66. MonitorButtons() /*Monitor the IDCMP port*/
  67. {
  68.    ULONG Class;
  69.    struct Gadget *gadg;
  70.    struct IntuiMessage *mesg;
  71.    
  72.    for(;;)
  73.    {
  74.       Wait(1<<SearchWdw->UserPort->mp_SigBit);
  75.       while((mesg=(struct IntuiMessage *)GetMsg(SearchWdw->UserPort))!=NULL)
  76.       {
  77.          Class=mesg->Class;   /*Get the information*/
  78.          gadg=mesg->IAddress; 
  79.          ReplyMsg(mesg);      /*Reply to the message*/
  80.          switch(Class)
  81.          {
  82.             case CLOSEWINDOW: /*Close gadget == CANCEL*/
  83.                return(FALSE);
  84.             case GADGETUP:
  85.                switch(gadg->GadgetID)
  86.                {
  87.                   case 8:  /*Cancel*/
  88.                      return(FALSE);
  89.                   case 7:  /*Wait*/
  90.                      return(MAYBE);
  91.                   case 6:  /*OK*/
  92.                      return(TRUE);
  93.                   case 1:
  94.                      ActivateGadget(&ReplaceWith,SearchWdw,NULL);
  95.                         /*Activate the Replace with... string gadget when*/
  96.                         /*the user presses RETURN in the Search for...*/
  97.                         /*gadget*/
  98.                      return(NONONO); /*Don't alter a flag :-) */
  99.                }
  100.          }
  101.       }
  102.    }
  103. }
  104.  
  105.  
  106. extern struct LineItem *SearchText(Item,Pos,string,scase,partial)
  107.       /*Search an outline for a particular string of characters*/
  108. struct LineItem *Item; /*Item to start searching on*/
  109. USHORT *Pos;           /*Position in that item to start on*/
  110. char *string;          /*Search string*/
  111. BYTE scase,partial;    /*scase  - TRUE if case matters, FALSE otherwise*/
  112.                        /*partial-TRUE if it may be a part of a word*/
  113. {
  114.    int c,found,start,thestart;
  115.    struct LineItem *cur,*theitem;
  116.    BYTE status=FALSE;
  117.    char chr,fchr;
  118.    
  119.    if(!scase) /*If case sensitive, convert the string to all uppercase*/
  120.       for(c=0;c<strlen(string);c++)
  121.          string[c]=toupper(string[c]);
  122.          
  123.    if(*Pos >= strlen(Item->Text)) /*If at the end of the line*/
  124.    {
  125.       start=0;  /*Start of next line*/
  126.       Item=(struct LineItem *)Item->NextItem;
  127.    }
  128.    else
  129.       start=*Pos;  /*Else, start at cursor position*/
  130.       
  131.    for(cur=(struct LineItem *)Item;cur != NULL && !status;/*Search until end*/
  132.          cur=(struct LineItem *)cur->NextItem) /*or text is found*/
  133.       for(c=start;c<strlen(cur->Text) && !status ;++c)
  134.       {        /*Loop that searches each line:  */
  135.          start=0;
  136.                   
  137.          if((partial) || ( (!partial) && ((c==0) || (cur->Text[c-1]==' ') )))
  138.                /*If partial words are OK, or if not, if the character*/
  139.                /*currently being checked is the first letter in a word*/
  140.          {
  141.             if(!scase)  /*If case is important*/
  142.                chr=toupper(cur->Text[c]); /*Switch to uppercase (see above)*/
  143.             else
  144.                chr=cur->Text[c];
  145.  
  146.             if(string[0]==chr) /*If first character matches...*/
  147.             {
  148.                status=TRUE;
  149.                theitem=(struct LineItem *)cur;
  150.                thestart=c;
  151.                for(found=1;found<strlen(string) && status ;found++)
  152.                {     /*see if the rest matches...*/
  153.                   if(!scase)
  154.                      fchr=toupper(cur->Text[c+found]);
  155.                   else
  156.                      fchr=cur->Text[c+found];
  157.                      
  158.                   if(fchr!=string[found])
  159.                      status=FALSE;
  160.                }                    /*If the word is a prefix of another word*/
  161.                if(cur->Text[c+found] != ' ' && cur->Text[c+found]!= NULL &&
  162.                         !partial)
  163.                   status = FALSE;      /*return FALSE*/
  164.             }
  165.          }
  166.       }
  167.    if(status) /*If found...*/
  168.    {
  169.       *Pos=thestart;    /*Return the position of the start of the text*/
  170.       return(theitem);  /*And the item that it is found in*/
  171.    }                    /*(so that the cursor can be moved accordingly)*/
  172.    else
  173.       return(NULL);     /*Otherwise, nothing*/
  174. }
  175.  
  176. DoSearch(again,arexx)  /*Main entry point for 'Search/Replace' and 'Next'*/
  177. BYTE again,arexx;      /*Again:  TRUE if 'Next', FALSE if 'Search/Replace'*/
  178. {
  179.    char Buffer[8],reslt[160],preservation[80];
  180.    int status;
  181.    UBYTE TempY;
  182.    struct LineItem *tempitem,*result;
  183.    struct LineItem *firstitem=(struct LineItem *)CurrentItem;
  184.    
  185.    USHORT Pos=(again && again != 100) ? CurX-MinX(CurrentItem)+1 :
  186.           CurX-MinX(CurrentItem);
  187.    
  188.    
  189.    status = (again) ? TRUE : GetSRParameters();
  190.          /*If 'Next', search no matter what.  Otherwise, depends on user*/
  191.    CancelInvs();  /*Cancel text highlighting*/
  192.    if(ErrorInTitle)     /*Cancel any errors in the title bar*/
  193.       TitleErrorCancel();
  194.    
  195.    
  196.    if(status)     /*If it's OK to search*/
  197.    {
  198.       strcpy(preservation,parameters.Search);   /*Store the search string*/
  199.             /*so if SearchText turns it to all caps, we'll still have the*/
  200.             /*original*/
  201.             
  202.       result=(struct LineItem *) /*Search the text*/
  203.             SearchText(CurrentItem,&Pos,parameters.Search,parameters.cse,
  204.             parameters.partial);
  205.    
  206.       if(result!=NULL)  /*If found...*/
  207.       {
  208.          /*Place the cursor at the start of the word*/
  209.          if(result!=FirstScrnItem || result!=firstitem)
  210.          {
  211.             FirstScrnItem=CurrentItem=(struct LineItem *)result;
  212.             PrintItemList(CurrentItem,1);
  213.          }
  214.          PlotCursor(MinX(CurrentItem)+Pos,1);
  215.          if(parameters.rep) /*If a search and replace*/
  216.          {                  /*Replace!!!!*/
  217.             strcpy(reslt,&(CurrentItem->Text[Pos+strlen(parameters.Search)]));
  218.             strins(reslt,parameters.Replace);
  219.             CurrentItem->Text[Pos]=NULL;
  220.             strins(reslt,CurrentItem->Text);
  221.                        
  222.                /*Break the line apart if necessary*/
  223.             tempitem=(struct LineItem *)BreakLineApart(CurrentItem,
  224.                   CurrentItem->NextItem,reslt);
  225.             
  226.             PlotCursor(1,CurY);
  227.             Buffer[0]=CSI;
  228.             Buffer[1]=0x4b;
  229.             WriteConsole(Buffer,2);
  230.             TempY=CurY;
  231.             if(tempitem==CurrentItem)
  232.                PrintItem(CurrentItem);
  233.             else
  234.                PrintItemList(CurrentItem,CurY);
  235.             PlotCursor(MinX(CurrentItem)+Pos,TempY);
  236.             CheckModified();  /*Text has been modified*/
  237.          }
  238.          strcpy(parameters.Search,preservation);
  239.          return(TRUE);
  240.       }
  241.       else  /*If it wasn't found*/
  242.       {
  243.          strcpy(parameters.Search,preservation);
  244.          if(!arexx)  /*If this wasn't an ARexx command*/
  245.             TitleError("Wasn't found!!!");
  246.          return(FALSE);
  247.       }
  248.    }
  249. }
  250.  
  251. void ModifyParams(search,replace,case_s,partial,s_repl)
  252. char *search,*replace;
  253. BYTE case_s,partial,s_repl;
  254. {
  255.    if(search[0]!=NULL)
  256.       strcpy(parameters.Search,search);
  257.    if(replace[0]!=NULL)
  258.       strcpy(parameters.Replace,replace);
  259.    if(case_s!=100)
  260.       parameters.cse=case_s;
  261.    if(partial!=100)
  262.       parameters.partial=partial;
  263.    if(s_repl!=100)
  264.       parameters.rep=s_repl;
  265. }
  266.  
  267. void ReplaceAll(verify) /*Search/replace entire document at once*/
  268. BYTE verify;
  269. {
  270.    BYTE stat;
  271.    
  272.    if(verify)
  273.    {
  274.       ModifyParams("","",100,100,FALSE);
  275.       while(DoSearch(TRUE,TRUE)) /*Search for text*/
  276.       {
  277.          if(stat=AskChange()) /*Ask user what to do*/
  278.          {
  279.             if(stat==TRUE) /*Replace*/
  280.             {
  281.                ModifyParams("","",100,100,TRUE);
  282.                DoSearch(100,TRUE);
  283.                ModifyParams("","",100,100,FALSE);
  284.             } /*Else goto next*/
  285.          }
  286.          else
  287.             return;  /*Else cancel*/
  288.       }
  289.       TitleError("No more found");
  290.    }
  291.    else   /*Do all without verification*/
  292.    {
  293.       ModifyParams("","",100,100,TRUE);
  294.       while(DoSearch(TRUE,TRUE));
  295.    }
  296. }
  297.  
  298. BYTE AskChange() /*Ask user if he wants to do replace*/
  299. {
  300.    struct Window *ReplAllWdw;
  301.    struct IntuiMessage *mesg;
  302.    struct Gadget *gadg;
  303.    
  304.    NewWindowStructure2.Screen=(struct Screen *)Screen; /*'Liner screen*/
  305.    if((ReplAllWdw=(struct Window *)OpenWindow(&NewWindowStructure2))==NULL)
  306.       return(FALSE); /*Open the window*/
  307.       
  308.    PrintIText(ReplAllWdw->RPort,&IntuiTextList2,0,0);
  309.    Wait(1<<ReplAllWdw->UserPort->mp_SigBit); /*Wait for gadget press*/
  310.  
  311.    if((mesg=(struct IntuiMessage *)GetMsg(ReplAllWdw->UserPort))==NULL)
  312.    {
  313.       CloseWindow(ReplAllWdw);
  314.       return(FALSE); /*Get the message*/
  315.    }
  316.    
  317.    gadg=(struct Gadget *)mesg->IAddress;/*Get the gadget structure's addr*/
  318.    
  319.    ReplyMsg(mesg); /*Reply to it*/
  320.    
  321.    
  322.    CloseWindow(ReplAllWdw); /*Close the window*/
  323.    return(gadg->GadgetID); /*Return the gadget ID*/
  324. }
  325.  
  326. /*End of Search.c*/
  327.